<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "https://www.w3.org/TR/html4/loose.dtd">
<html lang="zh-CN"><head><meta http-equiv="Content-Type" content="text/html; charset=utf-8"><meta http-equiv="Content-Language" content="zh-CN"><link href="stylesheet.css" media="all" rel="stylesheet" type="text/css">
<title>消息格式</title>
<script> var _hmt = _hmt || []; (function() { var hm = document.createElement("script"); hm.src = "https://hm.baidu.com/hm.js?d286c55b63a3c54a1e43d10d4c203e75"; var s = document.getElementsByTagName("script")[0]; s.parentNode.insertBefore(hm, s); })(); </script>
</head><body class="SECT1">
<div>
<table summary="Header navigation table" width="100%" border="0" cellpadding="0" cellspacing="0">
<tr><th colspan="5" align="center" valign="bottom">PostgreSQL 8.2.3 中文文档</th></tr>
<tr><td width="10%" align="left" valign="top"><a href="protocol-message-types.html" accesskey="P">后退</a></td><td width="10%" align="left" valign="top"><a href="protocol.html">快退</a></td><td width="60%" align="center" valign="bottom">章44. 前/后端协议</td><td width="10%" align="right" valign="top"><a href="protocol.html">快进</a></td><td width="10%" align="right" valign="top"><a href="protocol-error-fields.html" accesskey="N">前进</a></td></tr>
</table>
<hr align="LEFT" width="100%"></div>
<div class="SECT1"><h1 class="SECT1"><a name="PROTOCOL-MESSAGE-FORMATS">44.4. 消息格式</a></h1>
<p>本节描述各种消息的详细格式。每种消息都标记为它是由一个前端(F)，一个后端(B)或者两者(F &amp; B)发送的。请注意，尽管每条消息在开头都包含一个字节计数，消息格式也定义为可以不用参考字节计数就可以找到消息的结尾。这样就增加了有效性检查。CopyData 消息是一个例外，因为它形成一个数据流的一部分；任意独立的 CopyData 消息可能是无法自解释的。</p>
<div class="VARIABLELIST">
<dl>
<dt>AuthenticationOk (B)</dt>
<dd><p>&#13;</p>
<div class="VARIABLELIST">
<dl>
<dt>Byte1('R')</dt>
<dd><p>标识该消息是一条认证请求。</p></dd>
<dt>Int32(8)</dt>
<dd><p>以字节记的消息内容长度，包括这个长度本身。</p></dd>
<dt>Int32(0)</dt>
<dd><p>声明该认证是成功的。</p></dd>
</dl>
</div>
<p>&#13;</p></dd>
<dt>AuthenticationKerberosV5 (B)</dt>
<dd><p>&#13;</p>
<div class="VARIABLELIST">
<dl>
<dt>Byte1('R')</dt>
<dd><p>标识该消息是一条认证请求。</p></dd>
<dt>Int32(8)</dt>
<dd><p>以字节记的消息内容长度，包括长度自身。</p></dd>
<dt>Int32(2)</dt>
<dd><p>声明需要 Kerberos V5 认证。</p></dd>
</dl>
</div></dd>
<dt>AuthenticationCleartextPassword (B)</dt>
<dd><p>&#13;</p>
<div class="VARIABLELIST">
<dl>
<dt>Byte1('R')</dt>
<dd><p>标识该消息是一条认证请求。</p></dd>
<dt>Int32(8)</dt>
<dd><p>以字节记的消息内容长度，包括长度自身。</p></dd>
<dt>Int32(3)</dt>
<dd><p>声明需要一个明文的口令。</p></dd>
</dl>
</div></dd>
<dt>AuthenticationCryptPassword (B)</dt>
<dd><p>&#13;</p>
<div class="VARIABLELIST">
<dl>
<dt>Byte1('R')</dt>
<dd><p>标识该消息是一条认证请求。</p></dd>
<dt>Int32(10)</dt>
<dd><p>以字节记的消息内容的长度，包括长度本身。</p></dd>
<dt>Int32(4)</dt>
<dd><p>声明需要一个 crypt() 加密的口令。</p></dd>
<dt>Byte2</dt>
<dd><p>加密口令使用的盐粒(salt)。</p></dd>
</dl>
</div>
<p>&#13;</p></dd>
<dt>AuthenticationMD5Password (B)</dt>
<dd><p>&#13;</p>
<div class="VARIABLELIST">
<dl>
<dt>Byte1('R')</dt>
<dd><p>标识这条消息是一个认证请求。</p></dd>
<dt>Int32(12)</dt>
<dd><p>以字节记的消息内容的长度，包括长度本身。</p></dd>
<dt>Int32(5)</dt>
<dd><p>声明需要一个 MD5 加密的口令。</p></dd>
<dt>Byte4</dt>
<dd><p>加密口令的时候使用的盐粒。</p></dd>
</dl>
</div>
<p>&#13;</p></dd>
<dt>AuthenticationSCMCredential (B)</dt>
<dd><p>&#13;</p>
<div class="VARIABLELIST">
<dl>
<dt>Byte1('R')</dt>
<dd><p>标识这条消息是一个认证请求。</p></dd>
<dt>Int32(8)</dt>
<dd><p>以字节计的消息内容长度，包括长度本身。</p></dd>
<dt>Int32(6)</dt>
<dd><p>声明需要一个 SCM 信任消息。</p></dd>
</dl>
</div>
<p>&#13;</p></dd>
<dt>BackendKeyData (B)</dt>
<dd><p>&#13;</p>
<div class="VARIABLELIST">
<dl>
<dt>Byte1('K')</dt>
<dd><p>标识该消息是一个取消键字数据。如果前端希望能够在稍后发出 CancelRequest 消息，那么它必须保存这个值。</p></dd>
<dt>Int32(12)</dt>
<dd><p>以字节记的消息内容的长度，包括长度本身。</p></dd>
<dt>Int32</dt>
<dd><p>后端的进程号(PID)</p></dd>
<dt>Int32</dt>
<dd><p>此后端的密钥</p></dd>
</dl>
</div>
<p>&#13;</p></dd>
<dt>Bind (F)</dt>
<dd><p>&#13;</p>
<div class="VARIABLELIST">
<dl>
<dt>Byte1('B')</dt>
<dd><p>标识该信息是一个绑定命令</p></dd>
<dt>Int32</dt>
<dd><p>以字节记的消息内容的长度，包括长度本身。</p></dd>
<dt>String</dt>
<dd><p>目标入口的名字(空字符串则选取未命名的入口)</p></dd>
<dt>String</dt>
<dd><p>源预备语句的名字(空字符串则选取未命名的预备语句)</p></dd>
<dt>Int16</dt>
<dd><p>后面跟着的参数格式代码的数目(在下面的 <tt class="REPLACEABLE"><i>C</i></tt> 中说明)。这个数值可以是零，表示没有参数，或者是参数都使用缺省格式(文本)；或者是一，这种情况下声明的格式代码应用于所有参数；或者它可以等于实际数目的参数。</p></dd>
<dt>Int16[<tt class="REPLACEABLE"><i>C</i></tt>]</dt>
<dd><p>参数格式代码。目前每个都必须是零(文本)或者一(二进制)。</p></dd>
<dt>Int16</dt>
<dd><p>后面跟着的参数值的数目(可能为零)。这些必须和查询需要的参数个数匹配。</p></dd>
</dl>
</div>
<p>然后，每个参数都会出现下面的字段对：</p>
<div class="VARIABLELIST">
<dl>
<dt>Int32</dt>
<dd><p>参数值的长度，以字节记(这个长度并不包含长度本身)。可以为零。一个特殊的情况是，-1 表示一个 NULL 参数值。在 NULL 的情况下，后面不会跟着数值字节。</p></dd>
<dt>Byte<tt class="REPLACEABLE"><i>n</i></tt></dt>
<dd><p>参数值，格式是关联的格式代码标明的。<tt class="REPLACEABLE"><i>n</i></tt> 是上面的长度。</p></dd>
</dl>
</div>
<p>在最后一个参数之后，出现下面的字段：</p>
<div class="VARIABLELIST">
<dl>
<dt>Int16</dt>
<dd><p>后面跟着的结果字段格式代码数目(下面的 <tt class="REPLACEABLE"><i>R</i></tt> 描述)。这个数目可以是零表示没有结果字段，或者结果字段都使用缺省格式(文本)；或者是一，这种情况下声明格式代码应用于所有结果字段(如果有的话)；或者它可以等于查询的结果字段的实际数目。</p></dd>
<dt>Int16[<tt class="REPLACEABLE"><i>R</i></tt>]</dt>
<dd><p>结果字段格式代码。目前每个必须是零(文本)或者一(二进制)。</p></dd>
</dl>
</div></dd>
<dt>BindComplete (B)</dt>
<dd><p>&#13;</p>
<div class="VARIABLELIST">
<dl>
<dt>Byte1('2')</dt>
<dd><p>标识消息为一个绑定结束标识符</p></dd>
<dt>Int32(4)</dt>
<dd><p>以字节记的消息长度，包括长度本身。</p></dd>
</dl>
</div>
<p>&#13;</p></dd>
<dt>CancelRequest (F)</dt>
<dd><p>&#13;</p>
<div class="VARIABLELIST">
<dl>
<dt>Int32(16)</dt>
<dd><p>以字节计的消息长度。包括长度本身。</p></dd>
<dt>Int32(80877102)</dt>
<dd><p>取消请求代码。选这个值是为了在高 16 位包含 <tt class="LITERAL">1234</tt> ，低 16 位包含 <tt class="LITERAL">5678</tt> 。为避免混乱，这个代码必须与协议版本号不同。</p></dd>
<dt>Int32</dt>
<dd><p>目标后端的进程号(PID)</p></dd>
<dt>Int32</dt>
<dd><p>目标后端的密钥</p></dd>
</dl>
</div>
<p>&#13;</p></dd>
<dt>Close (F)</dt>
<dd><p>&#13;</p>
<div class="VARIABLELIST">
<dl>
<dt>Byte1('C')</dt>
<dd><p>标识这条消息是一个 Close 命令。</p></dd>
<dt>Int32</dt>
<dd><p>以字节计的消息内容长度，包括长度本身。</p></dd>
<dt>Byte1</dt>
<dd><p>'<tt class="LITERAL">S</tt>'关闭一个准备的语句；或者'<tt class="LITERAL">P</tt>'关闭一个入口。</p></dd>
<dt>String</dt>
<dd><p>一个要关闭的预备语句或者入口的名字(一个空字符串选择未命名的预备语句或者入口)。</p></dd>
</dl>
</div></dd>
<dt>CloseComplete (B)</dt>
<dd><p>&#13;</p>
<div class="VARIABLELIST">
<dl>
<dt>Byte1('3')</dt>
<dd><p>标识消息是一个 Close 完毕指示器。</p></dd>
<dt>Int32(4)</dt>
<dd><p>以字节记的消息内容的长度，包括长度本身。</p></dd>
</dl>
</div>
<p>&#13;</p></dd>
<dt>CommandComplete (B)</dt>
<dd><p>&#13;</p>
<div class="VARIABLELIST">
<dl>
<dt>Byte1('C')</dt>
<dd><p>标识此消息是一个命令结束响应。</p></dd>
<dt>Int32</dt>
<dd><p>以字节记的消息内容的长度，包括长度本身。</p></dd>
<dt>String</dt>
<dd><p>命令标记。它通常是一个单字，标识那个命令完成。</p>
<p>对于 <tt class="COMMAND">INSERT</tt> 命令，标记是 <tt class="LITERAL">INSERT <tt class="REPLACEABLE"><i>oid</i></tt> <tt class="REPLACEABLE"><i>rows</i></tt></tt> ，这里的 <tt class="REPLACEABLE"><i>rows</i></tt> 是插入的行数。<tt class="REPLACEABLE"><i>oid</i></tt> 在 <tt class="REPLACEABLE"><i>rows</i></tt> 为 1 并且目标表有 OID 的时候是插入行的对象 ID ；否则 <tt class="REPLACEABLE"><i>oid</i></tt> 就是 0</p>
<p>对于 <tt class="COMMAND">DELETE</tt> 命令，标记是 <tt class="LITERAL">DELETE <tt class="REPLACEABLE"><i>rows</i></tt></tt> ，这里的 <tt class="REPLACEABLE"><i>rows</i></tt> 是删除的行数。</p>
<p>对于 <tt class="COMMAND">UPDATE</tt> 命令，标记是 <tt class="LITERAL">UPDATE <tt class="REPLACEABLE"><i>rows</i></tt></tt> ，这里的 <tt class="REPLACEABLE"><i>rows</i></tt> 是更新的行数。</p>
<p>对于 <tt class="COMMAND">MOVE</tt> 命令，标记是 <tt class="LITERAL">MOVE <tt class="REPLACEABLE"><i>rows</i></tt></tt> ，这里的 <tt class="REPLACEABLE"><i>rows</i></tt> 是游标未知改变的行数。</p>
<p>对于 <tt class="COMMAND">FETCH</tt> 命令，标记是 <tt class="LITERAL">FETCH <tt class="REPLACEABLE"><i>rows</i></tt></tt> ，这里的 <tt class="REPLACEABLE"><i>rows</i></tt> 是从游标中检索出来的行数。</p>
<p>对于 <tt class="COMMAND">COPY</tt> 命令，标记是 <tt class="LITERAL">COPY <tt class="REPLACEABLE"><i>rows</i></tt></tt> ，这里的 <tt class="REPLACEABLE"><i>rows</i></tt> 是拷贝的行数。</p></dd>
</dl>
</div>
<p>&#13;</p></dd>
<dt>CopyData (F &amp; B)</dt>
<dd><div class="VARIABLELIST">
<dl>
<dt>Byte1('d')</dt>
<dd><p>标识这条消息是一个 <tt class="COMMAND">COPY</tt> 数据。</p></dd>
<dt>Int32</dt>
<dd><p>以字节记的消息内容的长度，包括长度本身。</p></dd>
<dt>Byte<tt class="REPLACEABLE"><i>n</i></tt></dt>
<dd><p><tt class="COMMAND">COPY</tt> 数据流的一部分的数据。从后端发出的消息总是对应一个数据行，但是前端发出的消息可以任意分割数据流。</p></dd>
</dl>
</div></dd>
<dt>CopyDone (F &amp; B)</dt>
<dd><p>&#13;</p>
<div class="VARIABLELIST">
<dl>
<dt>Byte1('c')</dt>
<dd><p>标识这条信息是一个 <tt class="COMMAND">COPY</tt> 结束指示器。</p></dd>
<dt>Int32(4)</dt>
<dd><p>以字节计的消息内容长度，包括长度本身。</p></dd>
</dl>
</div>
<p>&#13;</p></dd>
<dt>CopyFail (F)</dt>
<dd><p>&#13;</p>
<div class="VARIABLELIST">
<dl>
<dt>Byte1('f')</dt>
<dd><p>标识这条消息是一个 <tt class="COMMAND">COPY</tt> 失败指示器。</p></dd>
<dt>Int32</dt>
<dd><p>以字节记的消息内容的长度，包括长度本身。</p></dd>
<dt>String</dt>
<dd><p>一个报告失败原因的错误信息。</p></dd>
</dl>
</div>
<p>&#13;</p></dd>
<dt>CopyInResponse (B)</dt>
<dd><p>&#13;</p>
<div class="VARIABLELIST">
<dl>
<dt>Byte1('G')</dt>
<dd><p>标识这条消息是一条 StartCopyIn(开始拷贝进入)响应消息。前端现在必须发送一条拷贝入数据。如果还没准备好做这些事情，那么发送一条 CopyFail 消息。</p></dd>
<dt>Int32</dt>
<dd><p>以字节记的消息内容的长度，包括长度本身。</p></dd>
<dt>Int8</dt>
<dd><p>0 表示全部的 <tt class="COMMAND">COPY</tt> 格式都是文本的(数据行由换行符分隔，字段由分隔字符分隔等等)。1 表示都是二进制的(类似 DataRow 格式)。参阅 <a href="sql-copy.html"><i>COPY</i></a> 获取更多信息。</p></dd>
<dt>Int16</dt>
<dd><p>数据中要拷贝的字段数(由下面的 <tt class="REPLACEABLE"><i>N</i></tt> 解释)。</p></dd>
<dt>Int16[<tt class="REPLACEABLE"><i>N</i></tt>]</dt>
<dd><p>每个字段将要用的格式代码，目前每个都必须是零(文本)或者一(二进制)。如果全部拷贝格式都是文本的，那么所有的都必须是零。</p></dd>
</dl>
</div>
<p>&#13;</p></dd>
<dt>CopyOutResponse (B)</dt>
<dd><p>&#13;</p>
<div class="VARIABLELIST">
<dl>
<dt>Byte1('H')</dt>
<dd><p>标识这条消息是一条 StartCopyOut(开始拷贝进出)响应消息。这条消息后面将跟着一条拷贝出数据消息。</p></dd>
<dt>Int32</dt>
<dd><p>以字节记的消息内容的长度，包括它自己。</p></dd>
<dt>Int8</dt>
<dd><p>0 表示全部拷贝格式都是文本(数据行由换行符分隔，字段由分隔字符分隔等等)。1 表示所有拷贝格式都是二进制的(类似于 DataRow 格式)。参阅 <a href="sql-copy.html"><i>COPY</i></a> 获取更多信息。</p></dd>
<dt>Int16</dt>
<dd><p>要拷贝的数据的字段的数目(在下面的 <tt class="REPLACEABLE"><i>N</i></tt> 说明)。</p></dd>
<dt>Int16[<tt class="REPLACEABLE"><i>N</i></tt>]</dt>
<dd><p>每个字段要试用的格式代码。目前每个都必须是零(文本)或者一(二进制)。如果全部的拷贝格式都是文本，那么所有的都必须是零。</p></dd>
</dl>
</div>
<p>&#13;</p></dd>
<dt>DataRow (B)</dt>
<dd><div class="VARIABLELIST">
<dl>
<dt>Byte1('D')</dt>
<dd><p>标识这个消息是一个数据行。</p></dd>
<dt>Int32</dt>
<dd><p>以字节记的消息内容的长度，包括长度自身。</p></dd>
<dt>Int16</dt>
<dd><p>后面跟着的字段值的个数(可能是零)。</p></dd>
</dl>
</div>
<p>然后，每个字段都会出现下面的数据域对：</p>
<div class="VARIABLELIST">
<dl>
<dt>Int32</dt>
<dd><p>字段值的长度，以字节记(这个长度不包括它自己)。可以为零。一个特殊的情况是，-1 表示一个 NULL 的字段值。在 NULL 的情况下就没有跟着数据字段。</p></dd>
<dt>Byte<tt class="REPLACEABLE"><i>n</i></tt></dt>
<dd><p>一个字段的数值，以相关的格式代码表示的格式展现。<tt class="REPLACEABLE"><i>n</i></tt> 是上面的长度。</p></dd>
</dl>
</div>
<p>&#13;</p></dd>
<dt>Describe (F)</dt>
<dd><p>&#13;</p>
<div class="VARIABLELIST">
<dl>
<dt>Byte1('D')</dt>
<dd><p>标识消息是一个 Describe(描述)命令。</p></dd>
<dt>Int32</dt>
<dd><p>以字节记的消息内容的长度，包括字节本身。</p></dd>
<dt>Byte1</dt>
<dd><p>'<tt class="LITERAL">S</tt>'描述一个预备语句；或者'<tt class="LITERAL">P</tt>'描述一个入口。</p></dd>
<dt>String</dt>
<dd><p>要描述的预备语句或者入口的名字(或者一个空字符串，就会选取未命名的预备语句或者入口)。</p></dd>
</dl>
</div></dd>
<dt>EmptyQueryResponse (B)</dt>
<dd><p>&#13;</p>
<div class="VARIABLELIST">
<dl>
<dt>Byte1('I')</dt>
<dd><p>标识这条消息是对一个空查询字符串的响应。这个消息替换了 CommandComplete</p></dd>
<dt>Int32(4)</dt>
<dd><p>以字节记的消息内容长度，包括它自己。</p></dd>
</dl>
</div>
<p>&#13;</p></dd>
<dt>ErrorResponse (B)</dt>
<dd><p>&#13;</p>
<div class="VARIABLELIST">
<dl>
<dt>Byte1('E')</dt>
<dd><p>标识消息是一条错误</p></dd>
<dt>Int32</dt>
<dd><p>以字节记的消息内容的长度，包括长度本身。</p></dd>
</dl>
</div>
<p>消息体由一个或多个标识出来的字段组成，后面跟着一个字节零作为终止符。字段可以以任何顺序出现。对于每个字段都有下面的东西：</p>
<div class="VARIABLELIST">
<dl>
<dt>Byte1</dt>
<dd><p>一个标识字段类型的代码；如果为零，这就是消息终止符并且不会跟着有字符串。目前定义的字段类型在<a href="protocol-error-fields.html">节44.5</a>列出。因为将来可能增加更多的字段类型，所以前端应该不声不响地忽略不认识类型的字段。</p></dd>
<dt>String</dt>
<dd><p>字段值</p></dd>
</dl>
</div>
<p>&#13;</p></dd>
<dt>Execute (F)</dt>
<dd><p>&#13;</p>
<div class="VARIABLELIST">
<dl>
<dt>Byte1('E')</dt>
<dd><p>标识消息识一个 Execute 命令。</p></dd>
<dt>Int32</dt>
<dd><p>以字节记的消息内容的长度，包括长度自身。</p></dd>
<dt>String</dt>
<dd><p>要执行的入口的名字(空字符串选定未命名的入口)。</p></dd>
<dt>Int32</dt>
<dd><p>要返回的最大行数，如果入口包含返回行的查询(否则忽略)。零标识"没有限制"。</p></dd>
</dl>
</div></dd>
<dt>Flush (F)</dt>
<dd><p>&#13;</p>
<div class="VARIABLELIST">
<dl>
<dt>Byte1('H')</dt>
<dd><p>标识消息识一条 Flush 命令。</p></dd>
<dt>Int32(4)</dt>
<dd><p>以字节记的消息内容的长度，包括长度本身。</p></dd>
</dl>
</div>
<p>&#13;</p></dd>
<dt>FunctionCall (F)</dt>
<dd><p>&#13;</p>
<div class="VARIABLELIST">
<dl>
<dt>Byte1('F')</dt>
<dd><p>标识消息是一个函数调用。</p></dd>
<dt>Int32</dt>
<dd><p>以字节记的消息内容的长度，包括长度本身。</p></dd>
<dt>Int32</dt>
<dd><p>声明待调用的函数的对象标识(OID)。</p></dd>
<dt>Int16</dt>
<dd><p>后面跟着的参数格式代码的数目(用下面的 <tt class="REPLACEABLE"><i>C</i></tt> 表示)。它可以是零，表示没有参数，或者是所有参数都试用缺省格式(文本)；或者是一，这种情况下声明的格式代码应用于所有参数；或者它可以等于参数的实际个数。</p></dd>
<dt>Int16[<tt class="REPLACEABLE"><i>C</i></tt>]</dt>
<dd><p>参数格式代码。目前每个必须是零(文本)或者一(二进制)。</p></dd>
<dt>Int16</dt>
<dd><p>声明提供给函数的参数个数</p></dd>
</dl>
</div>
<p>然后，每个参数都出现下面字段对：</p>
<div class="VARIABLELIST">
<dl>
<dt>Int32</dt>
<dd><p>以字节记的参数值的长度(不包括长度自己)。可以为零。一个特殊的例子是，-1 表示一个 NULL 参数值。如果是 NULL ，则没有参数字节跟在后面。</p></dd>
<dt>Byte<tt class="REPLACEABLE"><i>n</i></tt></dt>
<dd><p>参数的值，格式是用相关的格式代码表示的。<tt class="REPLACEABLE"><i>n</i></tt> 是上面的长度。</p></dd>
</dl>
</div>
<p>在最后一个参数之后，出现下面的字段：</p>
<div class="VARIABLELIST">
<dl>
<dt>Int16</dt>
<dd><p>函数结果的格式代码。目前必须是零(文本)或者一(二进制)。</p></dd>
</dl>
</div>
<p>&#13;</p></dd>
<dt>FunctionCallResponse (B)</dt>
<dd><p>&#13;</p>
<div class="VARIABLELIST">
<dl>
<dt>Byte1('V')</dt>
<dd><p>标识这条消息是一个函数调用结果</p></dd>
<dt>Int32</dt>
<dd><p>以字节计的消息内容长度，包括长度本身。</p></dd>
<dt>Int32</dt>
<dd><p>以字节记的函数结果值的长度(不包括长度本身)。可以为零。一个特殊的情况是 -1 表示 NULL 函数结果。如果是 NULL 则后面没有数值字节跟随。</p></dd>
<dt>Byte<tt class="REPLACEABLE"><i>n</i></tt></dt>
<dd><p>函数结果的值，格式是相关联的格式代码标识的。<tt class="REPLACEABLE"><i>n</i></tt> 是上面的长度。</p></dd>
</dl>
</div>
<p>&#13;</p></dd>
<dt>NoData (B)</dt>
<dd><p>&#13;</p>
<div class="VARIABLELIST">
<dl>
<dt>Byte1('n')</dt>
<dd><p>标识这条消息是一个无数据指示器</p></dd>
<dt>Int32(4)</dt>
<dd><p>以字节计的消息内容长度，包括长度本身。</p></dd>
</dl>
</div>
<p>&#13;</p></dd>
<dt>NoticeResponse (B)</dt>
<dd><p>&#13;</p>
<div class="VARIABLELIST">
<dl>
<dt>Byte1('N')</dt>
<dd><p>标识这条消息是一个通知</p></dd>
<dt>Int32</dt>
<dd><p>以字节计的消息内容长度，包括长度本身。</p></dd>
</dl>
</div>
<p>消息体由一个或多个标识字段组成，后面跟着字节零作为中止符。字段可以以任何顺序出现。对于每个字段，都有下面的东西：</p>
<div class="VARIABLELIST">
<dl>
<dt>Byte1</dt>
<dd><p>一个标识字段类型的代码；如果为零，那么它就是消息终止符，并且后面不会跟着字符串。目前定义的字段类型在<a href="protocol-error-fields.html">节44.5</a>里列出。因为将来可能会增加更多字段类型，所以前端应该将不识别的字段安静地忽略掉。</p></dd>
<dt>String</dt>
<dd><p>字段值</p></dd>
</dl>
</div>
<p>&#13;</p></dd>
<dt>NotificationResponse (B)</dt>
<dd><p>&#13;</p>
<div class="VARIABLELIST">
<dl>
<dt>Byte1('A')</dt>
<dd><p>标识这条消息是一个通知响应</p></dd>
<dt>Int32</dt>
<dd><p>以字节计的消息内容长度，包括长度本身。</p></dd>
<dt>Int32</dt>
<dd><p>通知后端进程地进程 ID</p></dd>
<dt>String</dt>
<dd><p>触发通知的条件的名字</p></dd>
<dt>String</dt>
<dd><p>从通知进程传递过来的额外的信息。目前，这个特性还未实现，因此这个字段总是一个空字符串。</p></dd>
</dl>
</div>
<p>&#13;</p></dd>
<dt>ParameterDescription (B)</dt>
<dd><p>&#13;</p>
<div class="VARIABLELIST">
<dl>
<dt>Byte1('t')</dt>
<dd><p>标识消息是一个参数描述</p></dd>
<dt>Int32</dt>
<dd><p>以字节计的消息内容长度，包括长度本身。</p></dd>
<dt>Int16</dt>
<dd><p>语句所使用的参数的个数(可以为零)</p></dd>
</dl>
</div>
<p>然后，对每个参数，有下面的东西：</p>
<div class="VARIABLELIST">
<dl>
<dt>Int32</dt>
<dd><p>声明参数数据类型的对象 ID</p></dd>
</dl>
</div></dd>
<dt>ParameterStatus (B)</dt>
<dd><p>&#13;</p>
<div class="VARIABLELIST">
<dl>
<dt>Byte1('S')</dt>
<dd><p>标识这条消息是一个运行时参数状态报告</p></dd>
<dt>Int32</dt>
<dd><p>以字节计的消息内容长度，包括长度本身。</p></dd>
<dt>String</dt>
<dd><p>被报告的运行时参数的名字</p></dd>
<dt>String</dt>
<dd><p>参数的当前值</p></dd>
</dl>
</div></dd>
<dt>Parse (F)</dt>
<dd><p>&#13;</p>
<div class="VARIABLELIST">
<dl>
<dt>Byte1('P')</dt>
<dd><p>标识消息是一条 Parse 命令。</p></dd>
<dt>Int32</dt>
<dd><p>以字节计的消息内容长度，包括长度本身。</p></dd>
<dt>String</dt>
<dd><p>目的预备语句的名字(空字符串表示选取了未命名的预备语句)</p></dd>
<dt>String</dt>
<dd><p>要分析的查询字符串</p></dd>
<dt>Int16</dt>
<dd><p>声明的参数数据类型的数目(可以为零)。请注意这个参数并不意味着可能在查询字符串里出现的参数个数的意思，只是前端希望预先声明的类型的数目。</p></dd>
</dl>
</div>
<p>然后，对每个参数，有下面的东西：</p>
<div class="VARIABLELIST">
<dl>
<dt>Int32</dt>
<dd><p>声明参数数据类型的对象 ID 。在这里放一个零等效于不声明该类型。</p></dd>
</dl>
</div></dd>
<dt>ParseComplete (B)</dt>
<dd><p>&#13;</p>
<div class="VARIABLELIST">
<dl>
<dt>Byte1('1')</dt>
<dd><p>标识这条消息是一个 Parse 完成指示器。</p></dd>
<dt>Int32(4)</dt>
<dd><p>以字节计的消息内容长度，包括长度本身。</p></dd>
</dl>
</div>
<p>&#13;</p></dd>
<dt>PasswordMessage (F)</dt>
<dd><p>&#13;</p>
<div class="VARIABLELIST">
<dl>
<dt>Byte1('p')</dt>
<dd><p>标识这条消息是一个口令响应。</p></dd>
<dt>Int32</dt>
<dd><p>以字节计的消息内容长度，包括长度本身。</p></dd>
<dt>String</dt>
<dd><p>口令(如果要求了，就是加密后的)。</p></dd>
</dl>
</div></dd>
<dt>PortalSuspended (B)</dt>
<dd><p>&#13;</p>
<div class="VARIABLELIST">
<dl>
<dt>Byte1('s')</dt>
<dd><p>标识这条消息是一个入口挂起指示器。请注意这个消息只出现在达到一条 Execute 消息的行计数限制的时候。</p></dd>
<dt>Int32(4)</dt>
<dd><p>以字节计的消息内容长度，包括长度本身。</p></dd>
</dl>
</div>
<p>&#13;</p></dd>
<dt>Query (F)</dt>
<dd><p>&#13;</p>
<div class="VARIABLELIST">
<dl>
<dt>Byte1('Q')</dt>
<dd><p>标识消息是一个简单查询。</p></dd>
<dt>Int32</dt>
<dd><p>以字节计的消息内容长度，包括长度本身。</p></dd>
<dt>String</dt>
<dd><p>查询字符串自身</p></dd>
</dl>
</div>
<p>&#13;</p></dd>
<dt>ReadyForQuery (B)</dt>
<dd><p>&#13;</p>
<div class="VARIABLELIST">
<dl>
<dt>Byte1('Z')</dt>
<dd><p>标识消息类型。在后端为新的查询循环准备好的时候，总会发送 ReadyForQuery</p></dd>
<dt>Int32(5)</dt>
<dd><p>以字节计的消息内容长度，包括长度本身。</p></dd>
<dt>Byte1</dt>
<dd><p>当前后端事务状态指示器。可能的值是空闲状况下的'<tt class="LITERAL">I</tt>'(不在事务块里)；在事务块里是'<tt class="LITERAL">T</tt>'；或者在一个失败的事务块里是'<tt class="LITERAL">E</tt>'(在事务块结束之前，任何查询都将被拒绝)。</p></dd>
</dl>
</div>
<p>&#13;</p></dd>
<dt>RowDescription (B)</dt>
<dd><p>&#13;</p>
<div class="VARIABLELIST">
<dl>
<dt>Byte1('T')</dt>
<dd><p>标识消息是一个行描述</p></dd>
<dt>Int32</dt>
<dd><p>以字节计的消息内容长度，包括长度本身。</p></dd>
<dt>Int16</dt>
<dd><p>声明在一个行里面的字段数目(可以为零)</p></dd>
</dl>
</div>
<p>然后对于每个字段，有下面的东西：</p>
<div class="VARIABLELIST">
<dl>
<dt>String</dt>
<dd><p>字段名字</p></dd>
<dt>Int32</dt>
<dd><p>如果字段可以标识为一个特定表的字段，那么就是表的对象 ID ；否则就是零。</p></dd>
<dt>Int16</dt>
<dd><p>如果该字段可以标识为一个特定表的字段，那么就是该表字段的属性号；否则就是零。</p></dd>
<dt>Int32</dt>
<dd><p>字段数据类型的对象 ID </p></dd>
<dt>Int16</dt>
<dd><p>数据类型尺寸(参阅 <tt class="VARNAME">pg_type.typlen</tt>)。请注意负数表示变宽类型。</p></dd>
<dt>Int32</dt>
<dd><p>类型修饰词(参阅 <tt class="VARNAME">pg_attribute.atttypmod</tt>)。修饰词的含义是类型相关的。</p></dd>
<dt>Int16</dt>
<dd><p>用于该字段的格式码。目前会是零(文本)或者一(二进制)。从语句变种 Describe 返回的 RowDescription 里，格式码还是未知的，因此总是零。</p></dd>
</dl>
</div>
<p>&#13;</p></dd>
<dt>SSLRequest (F)</dt>
<dd><p>&#13;</p>
<div class="VARIABLELIST">
<dl>
<dt>Int32(8)</dt>
<dd><p>以字节计的消息内容长度，包括长度本身。</p></dd>
<dt>Int32(80877103)</dt>
<dd><p>SSL 请求码。选取的数值在高 16 位里包含 <tt class="LITERAL">1234</tt> ，在低 16 位里包含 <tt class="LITERAL">5679</tt> 。为了避免混淆，这个编码必须和任何协议版本号不同。</p></dd>
</dl>
</div>
<p>&#13;</p></dd>
<dt>StartupMessage (F)</dt>
<dd><p>&#13;</p>
<div class="VARIABLELIST">
<dl>
<dt>Int32</dt>
<dd><p>以字节计的消息内容长度，包括长度本身。</p></dd>
<dt>Int32(196608)</dt>
<dd><p>协议版本号。高 16 位是主版本号(对这里描述的协议而言是 3)。低 16 位是次版本号(对于这里描述的协议而言是 0)。</p></dd>
</dl>
</div>
<p>协议版本号后面跟着一个或多个参数名和值字符串的配对。要求在最后一个名字/数值对后面有个字节零。参数可以以任意顺序出现。<tt class="LITERAL">user</tt> 是必须的，其它都是可选的。每个参数都是这样声明的：</p>
<div class="VARIABLELIST">
<dl>
<dt>String</dt>
<dd><p>参数名。目前可以识别的名字是：</p>
<div class="VARIABLELIST">
<dl>
<dt><tt class="LITERAL">user</tt></dt>
<dd><p>用于连接的数据库用户名。必须；无缺省。</p></dd>
<dt><tt class="LITERAL">database</tt></dt>
<dd><p>要连接的数据库。缺省是用户名。</p></dd>
<dt><tt class="LITERAL">options</tt></dt>
<dd><p>给后端的命令行参数。这个特性已经废弃，更好的方法是设置单独的运行时参数。</p></dd>
</dl>
</div>
<p>除了上面的外，在后端启动的时候可以设置的任何运行时参数都可以列出来。这样的设置将在后端启动的时候附加(在分析了命令行参数之后，如果有的话)。这些值将成为会话缺省。</p></dd>
<dt>String</dt>
<dd><p>参数值</p></dd>
</dl>
</div>
<p>&#13;</p></dd>
<dt>Sync (F)</dt>
<dd><p>&#13;</p>
<div class="VARIABLELIST">
<dl>
<dt>Byte1('S')</dt>
<dd><p>表示该消息为一条 Sync 命令。</p></dd>
<dt>Int32(4)</dt>
<dd><p>以字节计的消息内容长度，包括长度本身。</p></dd>
</dl>
</div>
<p>&#13;</p></dd>
<dt>Terminate (F)</dt>
<dd><p>&#13;</p>
<div class="VARIABLELIST">
<dl>
<dt>Byte1('X')</dt>
<dd><p>标识消息是一个终止消息。</p></dd>
<dt>Int32(4)</dt>
<dd><p>以字节计的消息内容长度，包括长度本身。</p></dd>
</dl>
</div>
<p>&#13;</p></dd>
</dl>
</div>
</div>
<div>
<hr align="LEFT" width="100%">
<table summary="Footer navigation table" width="100%" border="0" cellpadding="0" cellspacing="0">
<tr><td width="33%" align="left" valign="top"><a href="protocol-message-types.html" accesskey="P">后退</a></td><td width="34%" align="center" valign="top"><a href="index.html" accesskey="H">首页</a></td><td width="33%" align="right" valign="top"><a href="protocol-error-fields.html" accesskey="N">前进</a></td></tr>
<tr><td width="33%" align="left" valign="top">消息数据类型</td><td width="34%" align="center" valign="top"><a href="protocol.html" accesskey="U">上一级</a></td><td width="33%" align="right" valign="top">错误和通知消息字段</td></tr>
</table>
</div>
</body></html>